package com.plian.system.controller.hr.dept;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.plian.Tools.*;
import com.plian.Tools.base.BaseController;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.annotation.LogOperation;
import com.plian.system.cache.DeptCache;
import com.plian.system.common.status.CustomCode;
import com.plian.system.entity.hr.dept.Dept;
import com.plian.system.entity.hr.staff.StaffFiles;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.hr.dept.IDeptService;
import com.plian.system.service.hr.staff.IStaffFilesService;
import com.plian.system.vo.hr.dept.DeptVO;
import com.plian.system.wrapper.hr.dept.DeptWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * 部门基础信息 控制器
 *
 * @author gangan
 * @since 2019-08-07
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("api/dept")
public class DeptController extends BaseController {

	private IDeptService deptService;

	private IStaffFilesService staffFilesService;

	private DeptWrapper deptWrapper;

	/**
	* 详情
	*/
	@PostMapping("/detail")
	public R<DeptVO> detail(@RequestBody Dept dept) {
		Dept detail = deptService.getOne(Condition.getQueryWrapper(dept));
		DeptVO deptVO = deptWrapper.entityToVO(detail);
		return R.data(deptVO);
	}

	/**
	* 分页 部门基础信息
	*/
	@PostMapping("/list")
	public ListResult<DeptVO> list(@Valid @RequestBody Query query) {
		if(query.getAscs()==null&&query.getDescs()==null){
			query.setAscs("dept_code");
		}
		List<SearchEntity> entityList = query.getSearch();
		QueryWrapper<Dept> queryWrapper = SearchParamEntiy.getQueryWrapper(
				Condition.getQueryWrapper(new Dept()), entityList
		);
		queryWrapper.eq("create_company_id", TokenUtil.getTokenOrgId());
		IPage<Dept> pages = deptService.page(Condition.getPage(query), queryWrapper);
		List<DeptVO> deptVOS = deptWrapper.entityToVO(pages.getRecords());
		ListResult<DeptVO> listResult = new ListResult<>(CommonCode.SUCCESS);
		listResult.setList(deptVOS);
		listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
		return listResult;
	}



	/**
	* 新增或修改 部门基础信息
	*/
	@PostMapping("/submit")
	@LogOperation("部门基础信息-提交")
	public R submit(@Valid @RequestBody Dept dept) {
		String checkResult = deptService.checkName(dept);
		if (StringUtil.isNotBlank(checkResult)) {
			return new R(CustomCode.builder().message(checkResult).code(1999).success(false).build());
		}
		checkResult = deptService.checkCode(dept);
		if (StringUtil.isNotBlank(checkResult)) {
			return new R(CustomCode.builder().message(checkResult).code(1999).success(false).build());
		}
		checkResult = deptService.checkDeptEnableDisable(dept);
		if (StringUtil.isNotBlank(checkResult)) {
			return new R(CustomCode.builder().message(checkResult).code(1999).success(false).build());
		}

		return deptService.saveOrUpdate(dept)
				? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
	}


	/**
	* 删除 部门基础信息
	*/
	@PostMapping("/remove")
	@LogOperation("部门基础信息-删除")
	public R remove(@RequestBody PageData pd) {
		List<String> ids = (List<String>)pd.get("ids");
		List<Long> idList = Func.toLongList(StringUtils.join(ids, StringPool.COMMA));
		if(idList.size()>0){
			LambdaQueryWrapper<StaffFiles> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(StaffFiles::getDepartmentNameId, idList);
			if(CollectionUtil.isNotEmpty(staffFilesService.list(queryWrapper))){
				return new R(CustomCode.builder().message("已被引用，不可删除").code(1999).success(false).build());
			}
		}

		if(deptService.isHavaChild(Func.toLong(ids))) {
			return new R(CustomCode.builder().message("存在下级部门，无法删除").code(1999).success(false).build());
		}

		boolean result = deptService.deleteLogic(idList);
		if (result){
			DeptCache.evictBatch(idList);
		}
		return result ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
	}

	@GetMapping("/tree")
	public ObjResult getTree() {
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("data", deptService.getTreeList());
		objResult.setPageData(pd);
		return objResult;
	}

	@GetMapping("/tree/inunit/{id}")
	public ObjResult getTreeInUnit(@PathVariable String id) {
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("data", deptService.getTreeInUnitList(id));
		objResult.setPageData(pd);
		return objResult;
	}

	@GetMapping("/tree/parent/{id}")
	public ObjResult getTreeInParent(@PathVariable long id) {
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("data", deptService.getTreeInParent(id));
		objResult.setPageData(pd);
		return objResult;
	}

	@PostMapping("/import")
	@LogOperation("部门基础信息-导入")
	public ObjResult importExcel(@RequestParam("file") MultipartFile multipartFile) throws IOException{
		String progressId = TokenUtil.getTokenUserId()+"_"+System.currentTimeMillis();
		CacheUtil.put("progress","progress",progressId + "#half:hour",0);
		InputStream inputStream = multipartFile.getInputStream();
		deptService.importExcel(progressId, inputStream);
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("progressId", progressId);
		objResult.setPageData(pd);
		return objResult;
	}

	@PostMapping("/preexport")
	public ObjResult preexport(@RequestBody String jsonString){
		String md5= DigestUtil.hmacMd5Hex(jsonString, TokenUtil.getTokenUserId() + "");
		File file = deptService.exportExcel(JSONObject.parseObject(jsonString));
		CacheUtil.put("baseinfo","dept:export:",md5+ "#half:hour",file);
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("progressId", md5);
		objResult.setPageData(pd);
		return objResult;
	}

	/**
	 * 输出excel
	 */
	@GetMapping("/export/{key}")
	public ResponseEntity<FileSystemResource> export(@PathVariable String key) {
		File file=CacheUtil.get("baseinfo","dept:export:",key+ "#half:hour",File.class);
		if (file == null) {
			return null;
		}
		HttpHeaders headers = new HttpHeaders();
		headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
		try {
			headers.add("Content-Disposition", "attachment; filename="+ URLEncoder.encode("部门基础信息","UTF-8")+".xlsx");
		} catch (UnsupportedEncodingException e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		headers.add("Pragma", "no-cache");
		headers.add("Expires", "0");
		headers.add("Last-Modified", new Date().toString());
		headers.add("ETag", String.valueOf(System.currentTimeMillis()));

		return ResponseEntity
			.ok()
			.headers(headers)
			.contentLength(file.length())
			.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
			.body(new FileSystemResource(file));
	}
}
